﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace RDPAddins.Common
{
    /// <summary>
    /// Represents RDS Channel
    /// </summary>
    public interface IChannel
    {
        /// <summary>
        /// Occurs when VirtualChannelInitEventProc(VirtualChannelInitEvent in RDS API) was called with ChannelEvents.Initialized(CHANNEL_EVENT_INITIALIZED in RDS API)
        /// </summary>
        event EventHandler Initialized;

        /// <summary>
        /// Occurs when VirtualChannelInitEventProc(VirtualChannelInitEvent in RDS API) was called with ChannelEvents.Connected(CHANNEL_EVENT_CONNECTED in RDS API)
        /// </summary>
        event EventHandler Connected;

        /// <summary>
        /// Occurs when VirtualChannelInitEventProc(VirtualChannelInitEvent in RDS API) was called with ChannelEvents.Disconnected(CHANNEL_EVENT_DISCONNECTED in RDS API)
        /// </summary>
        event EventHandler Disconnected;

        /// <summary>
        /// Occurs when VirtualChannelInitEventProc(VirtualChannelInitEvent in RDS API) was called with ChannelEvents.Terminated(CHANNEL_EVENT_TERMINATED in RDS API)
        /// </summary>
        event EventHandler Terminated;

        /// <summary>
        /// Occurs when VirtualChannelOpenEvent(VirtualChannelOpenEvent in RDS API) was called with ChannelEvents.DataRecived(CHANNEL_EVENT_DATA_RECEIVED in RDS API)
        /// </summary>
        event DataArrivedHandler DataArrived;

        /// <summary>
        /// Works similar to System.IO.Stream.Read
        /// </summary>
        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the channel.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the channel.</param>
        /// <param name="count">The maximum number of bytes to be read from the channel.</param>
        /// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available(including 0).</returns>
        int Read(byte[] buffer, int offset, int count);
        
        /// <summary>
        /// Works similar to System.IO.Stream.Write
        /// </summary>
        /// <param name="data">An array of bytes. This method sends bytes from buffer through channel.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin sending bytes through channel.</param>
        /// <param name="count">The number of bytes to be sent through channel.</param>
        void Write(byte[] data, int offset, int count);

        /// <summary>
        /// Creataes and returns stream. Stream is disposed when Disconnect event occurs.
        /// </summary>
        /// <returns>Retuns stream</returns>
        Stream GetStream();

        /// <summary>
        /// Gets Addin metadata
        /// </summary>
        IAddinMetadata Metadata { get; }

        /// <summary>
        /// Get IUI interface
        /// </summary>
        IUI UI { get; }
    }
    /// <summary>
    /// Represents the method that will handle the DataArrived event of a IChannel.
    /// </summary>
    /// <param name="dataLength">Specifies the size, in bytes, of the data. Use Read method of IChannel to read the data.</param>
    /// <param name="totalLength">Specifies the total size, in bytes, of the data written by a single write operation to the server end of the virtual channel.</param>
    /// <param name="dataFlags">Provides information about the chunk of data being received.</param>
    public delegate void DataArrivedHandler(uint dataLength, uint totalLength, DataParts dataFlags);

    /// <summary>
    /// Specifies constants that define which part of data chunk was sent.
    /// </summary>
    public enum DataParts
    {
        /// <summary>
        /// The chunk is the beginning of the data written by a single write operation.
        /// </summary>
        First = 0x01,
        /// <summary>
        /// The chunk is the end of the data written by a single write operation.
        /// </summary>
        Last = 0x02,
        /// <summary>
        /// The chunk is in the middle of a block of data written by a single write operation.
        /// </summary>
        Middle = 0,
        /// <summary>
        /// Combines the DataParts.First and DataParts.Last values. The chunk contains all the data from a single write operation.
        /// </summary>
        Only = First | Last,
        
    }
}
